<?php
class FileHandler extends Object
{
    protected static $usingPaths;

	public static function GetNameFromClass($class_name)
	{
	    return "$class_name.php";
	}

	public static function Read($file)
	{
		if (!file_exists($file))
			throw new Exception("File not found: $file");
		return file_get_contents($file);
	}

	public static function MakeDir($dir, $chmod = 0777)
	{
		if (!file_exists($dir))
		{
			mkdir($dir);
            chmod($dir, $chmod);
		}
	}

    public static function MakeDirRecursive($path, $basePath = null, $chmod = 0777)
    {
        $dirs = explode(DS, $path);
        foreach ($dirs as $dir)
        {
            $basePath = $basePath ? $basePath.DS.$dir : $dir;
            self::MakeDir($basePath);
        }
    }

    public static function ToClassName($file_name)
	{
		return String::CropEnd('.php', $file_name);
	}

    public static function StreamCopy($src, $dest)
    {
        $fsrc = fopen($src,'r');
        if (!$fsrc) throw new FileNotFoundException($src);
        $fdest = fopen($dest,'w');
        $len = stream_copy_to_stream($fsrc,$fdest);
        fclose($fsrc);
        fclose($fdest);
        return $len;
    }

    public static function Write($file, $data, $mode = 'w')
    {
        $handle = fopen($file, $mode);
        fwrite($handle, $data);
        fclose($handle);
        return true;
    }

    public static function Append($file, $data)
    {
        return self::Write($file, $data, 'a');
    }

    public static function Combine($combined_file, $files)
    {
        $combined = null;
        foreach ($files as $file)
        {
            if (file_exists($file))
                $combined .= "\n".FileHandler::Read($file);
        }
        FileHandler::Write($combined_file, $combined);
    }

    public static function Delete($filename)
    {
        if(file_exists($filename))
            unlink($filename);
    }

    public static function Remove($filename)
    {
        if(file_exists($filename))
        {
            if (is_file($filename))
                unlink($filename);
            else
                self::RemoveDir($filename);
        }
    }

    public static function RemoveDir($dirname)
    {
        if (!file_exists($dirname))
            return false;

        $dir = self::DirOpen($dirname);

        while($file = readdir($dir))
        {
            if (self::IsValid($file))
            {
                $file_path = $dirname.DS.$file;
                if (is_file($file_path))
                    unlink($file_path);
                else
                    FileHandler::RemoveDir($file_path);
            }
        }
        closedir($dir);
        rmdir($dirname);
        return true;
    }

    public static function Logs($message, $file)
    {
        $time_stamp = DatetimeBase::Now();
        $request_uri = $_SERVER['REQUEST_URI'];
        $ip = $_SERVER['REMOTE_ADDR'];
        $message = "[$time_stamp] [$ip] [$request_uri]: $message\n";
        $file = DIR_LOGS.DS.$file;
        FileHandler::Append($file, $message);
    }

    public static function GetSubs($dirname)
    {
        $dir = self::DirOpen($dirname);
        $out = array();
        while($file = readdir($dir))
        {
            if (self::IsValid($file))
            {
                $out[] = $file;
            }
        }
        closedir($dir);
        return $out;
    }

    public static function GetSubFiles($dirname, $ext = null, $limit = null, &$count = -1)
    {
        $dir = self::DirOpen($dirname);
        $out = array();
        $i = 0;
        while ($file = readdir($dir))
        {
            if (is_file($dirname.DS.$file) && (!$ext || $ext == self::GetExt($file)))
            {
                if (!$limit || $i < $limit) $out[] = $file;
                $i++;
                if ($i == $limit && $count == -1) break;
            }
        }
        closedir($dir);
        $count = $i;
        return $out;
    }

    public static function GetSubDirs($dirname, $return_full_path = false)
    {
        $dir = self::DirOpen($dirname);
        $out = array();
        while($file = readdir($dir))
        {
            if (self::IsValid($file))
            {
                $path = $dirname.DS.$file;
                if (is_dir($path))
                    $out[] = $return_full_path ? $path : $file;
            }
        }
        closedir($dir);
        return $out;
    }

    public static function DirOpen($dirname)
    {
        if (!file_exists($dirname))
            throw new Exception("'$dirname' not exist");

        $dir = is_dir($dirname) ? opendir($dirname) : null;
        if (!$dir)
            throw new Exception("Can not open $dirname");
        return $dir;
    }

    public static function SaveUsingPath($file, $path)
    {
        FileHandler::MakeDir(AppConfig::GetInstance()->DIR_CACHE_DATA);
        self::$usingPaths[$file] = $path;
        self::Export(AppConfig::GetInstance()->FILE_CACHE_USING, self::$usingPaths);
    }

    protected static function GetUsingPaths()
    {
        if (is_null(self::$usingPaths))
        {
            self::$usingPaths = array();
            $path = AppConfig::GetInstance()->FILE_CACHE_USING;
            try
            {
                if (file_exists($path))
                    self::$usingPaths = self::Load($path);
            }
            catch (Exception $ex)
            {}
        }
        return self::$usingPaths;
    }

    public static function GetUsingPath($file_name)
    {
        $paths = self::GetUsingPaths();
        return isset($paths[$file_name]) && file_exists($paths[$file_name]) ? $paths[$file_name] : null;
    }

    public static function ReadSerialize($file)
    {
        return unserialize(self::Read($file));
    }

    public static function WriteSerialize($file, $data, $mode = 'w')
    {
        return self::Write($file, serialize($data), $mode);
    }

    public static function GetExt($file)
    {
        return strtolower(pathinfo($file, PATHINFO_EXTENSION));
    }

    public static function GetName($file)
    {
        return pathinfo($file, PATHINFO_FILENAME);
    }

    public static function GetPath($file)
    {
        return pathinfo($file, PATHINFO_DIRNAME);
    }

    public static function IsValid($file)
    {
        return $file!= '.' && $file!= '..' && $file!= '.svn';
    }

    public static function SaveUploadedFile($dir, $name = null)
    {
        if (empty($_FILES)) return null;
        self::MakeDir($dir);
        foreach ($_FILES as $file)
        {
            $fname = $name ? $name : $file['name'];
            move_uploaded_file($file['tmp_name'], $dir.DS.$fname);
            break;
        }
        return $fname;
    }

    public static function SaveUploadedFiles($dir)
    {
        if (empty($_FILES)) return array();
        self::MakeDir($dir);
        $names = array();
        foreach ($_FILES as $file)
        {
            $fname = $name ? $name : $file['name'];
            move_uploaded_file($file['tmp_name'], $dir.DS.$fname);
            $names[] = $fname;
        }
        return $names;
    }

    public static function GetSubFilesSortByDate($dir)
    {
        $files = glob($dir.DS.'*.*');
        array_multisort(
            array_map( 'filemtime', $files),
            SORT_NUMERIC,
            SORT_DESC,
            $files
        );
        return $files;
    }

    public static function Upload($file, $url, $params = array())
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_VERBOSE, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        $post = array_merge(array("file_box"=>'@'.$file), $params);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        return curl_exec($ch);
    }

    public static function Export($file, $content)
    {
        $data = var_export($content, true);
        self::Write($file, "<?php return $data;\n?>");
    }

    public static function Load($file)
    {
        return include($file);
    }
}
?>